package com.shenmazg6.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shenmazg6.mapper.TbProductMapper;
import com.shenmazg6.mapper.TbUserMapper;
import com.shenmazg6.mapper.TbWareMapper;
import com.shenmazg6.pojo.TbOrder;
import com.shenmazg6.pojo.TbProduct;
import com.shenmazg6.pojo.TbUser;
import com.shenmazg6.pojo.TbWare;
import com.shenmazg6.service.TbOrderService;
import com.shenmazg6.mapper.TbOrderMapper;
import com.shenmazg6.state.OrderStateEnum;
import com.shenmazg6.utils.IdWorker;
import com.shenmazg6.utils.ResultResponse;
import com.shenmazg6.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author Think
* @description 针对表【tb_order(订单表)】的数据库操作Service实现
* @createDate 2022-12-20 10:55:19
*/
@Service
@Slf4j
public class TbOrderServiceImpl extends ServiceImpl<TbOrderMapper, TbOrder>
    implements TbOrderService{

    @Autowired
    TbUserMapper tbUserMapper;

    @Autowired
    TbProductMapper tbProductMapper;

    @Autowired
    TbWareMapper tbWareMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    private RedissonClient redisson;

    private String getRemoteOrderNO() {
        String apiUrl = "https://www.shenmazong.com/weixin/getOrderNo";

        try {
            // 创建客户端连接对象
            CloseableHttpClient client = HttpClients.createDefault();
            // 构建Get请求对象
            HttpGet get = new HttpGet(apiUrl);

            CloseableHttpResponse response = client.execute(get);

            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity);

            log.info("body" + body);
            ResultResponse resultResponse = JSON.parseObject(body, ResultResponse.class);
            return (String)resultResponse.getData();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultResponse buyOrder(BuyOrderVo buyOrderVo) {

        //--1 判断用户是否存在
        TbUser tbUser = tbUserMapper.selectOne(new QueryWrapper<TbUser>().lambda().eq(TbUser::getUserId, buyOrderVo.getUserId()));
        if(tbUser == null) {
            return ResultResponse.FAILED(404, "用户不存在");
        }

        //--2 判断产品是否存在
        TbProduct tbProduct = tbProductMapper.selectOne(new QueryWrapper<TbProduct>().lambda().eq(TbProduct::getProductId, buyOrderVo.getProductId()));
        if(tbProduct == null) {
            return ResultResponse.FAILED(404, "产品不存在");
        }
        TbOrder tbOrder = null;
        RLock lock = redisson.getLock("ware_lock");

        try {
            // 加锁
            lock.lock();

            // 判断库存
            // 这里没有判断SPU和SKU，需要完善
            TbWare tbWare = tbWareMapper.selectOne(new QueryWrapper<TbWare>().lambda().eq(TbWare::getProductId, buyOrderVo.getProductId()).last("limit 1"));
            if(tbWare == null) {
                return ResultResponse.FAILED(404, "产品没有库存");
            }
            if(tbWare.getWareCount() < buyOrderVo.getProductCount()) {
                return ResultResponse.FAILED(404, "产品库存不足");
            }

            //--3 下订单
            // 扣减库存
            tbWare.setWareCount(tbWare.getWareCount()-buyOrderVo.getProductCount());
            tbWare.setUpdateTime(null);
            tbWareMapper.updateById(tbWare);


        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            lock.unlock();
        }

        // 生成订单
        tbOrder = new TbOrder();
//        String orderNO = getRemoteOrderNO();
        tbOrder.setOrderNo(IdWorker.getId());
        tbOrder.setOrderAmount(buyOrderVo.getAmount());
        tbOrder.setProducId(tbProduct.getProductId());
        tbOrder.setProductName(tbProduct.getProductName());
        tbOrder.setProductSku(buyOrderVo.getSku());
        tbOrder.setProductCount(buyOrderVo.getProductCount());
        tbOrder.setUserId(tbUser.getUserId());
        tbOrder.setUserName(tbUser.getUserName());

        save(tbOrder);

        //--4 定时取消订单
        String message = JSON.toJSONString(tbOrder);
        rabbitTemplate.convertAndSend("orderQueue", message);

        // 返回订单信息
        return ResultResponse.SUCCESS(tbOrder);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelOrder(TbOrder tbOrder) {
        //-- 确认订单信息
        TbOrder order = getById(tbOrder.getOrderId());
        if(order == null) {
            log.error("订单不存在,id=" +tbOrder.getOrderId());
            return false;
        }

        //-- 修改订单状态
        if(!order.getOrderState().equals(OrderStateEnum.ORDER_NO_PAY.getCode())) {
            log.info("订单已处理,id=" +tbOrder.getOrderId());
            return true;
        }
        order.setOrderState(OrderStateEnum.ORDER_CANCEL.getCode());
        order.setUpdateTime(null);
        updateById(order);

        RLock lock = redisson.getLock("ware_back_lock");
        try {
            // 加锁
            lock.lock();

            //-- 回归库存:正常是通过SKU获取
            TbWare tbWare = tbWareMapper.selectOne(new QueryWrapper<TbWare>().lambda().eq(TbWare::getProductId, order.getProducId()).last("limit 1"));
            tbWare.setWareCount(tbWare.getWareCount()+order.getProductCount());
            tbWare.setUpdateTime(null);
            tbWareMapper.updateById(tbWare);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 解锁
            lock.unlock();
        }

        return true;
    }

    @Override
    public ResultResponse listByPage(PageInfoVo pageInfoVo) {

        Page<TbOrder> page = new Page<>(pageInfoVo.getPageNum(), pageInfoVo.getPageSize());
        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.lambda().orderByDesc(TbOrder::getOrderId);

        Page<TbOrder> tbOrderPage = page(page, wrapper);

        //
        Page<TbOrderVo> tbOrderVoPage = new Page<>();
        BeanUtils.copyProperties(tbOrderPage, tbOrderVoPage);

        //
        List<TbOrderVo> collect = tbOrderPage.getRecords().stream().map(item -> {
            TbOrderVo tbOrderVo = new TbOrderVo();
            BeanUtils.copyProperties(item, tbOrderVo);
            return tbOrderVo;
        }).collect(Collectors.toList());
        tbOrderVoPage.setRecords(collect);

        return ResultResponse.SUCCESS(tbOrderVoPage);
    }

    @Override
    public ResultResponse getOrderNo() {

        String apiUrl = "https://www.shenmazong.com/weixin/getOrderNo";

        try {
            // 创建客户端连接对象
            CloseableHttpClient client = HttpClients.createDefault();
            // 构建Get请求对象
            HttpGet get = new HttpGet(apiUrl);

            CloseableHttpResponse response = client.execute(get);

            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity);

            log.info("body" + body);
            ResultResponse resultResponse = JSON.parseObject(body, ResultResponse.class);
            return resultResponse;

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

        return ResultResponse.FAILED(500, "支付发生未知错误");
    }

    @Override
    public ResultResponse getPayCode(WxPayOrderVo wxPayOrderVo) {
        String apiUrl = "https://www.shenmazong.com/weixin/postOrderObj";

        try {
            // 创建客户端连接对象
            CloseableHttpClient client = HttpClients.createDefault();

            // 构建Post请求对象
            HttpPost post = new HttpPost(apiUrl);
            // 设置传送的内容类型是json格式
            post.setHeader("Content-Type", "application/json;charset=utf-8");
            // 接收的内容类型也是json格式
            post.setHeader("Accept", "application/json;charset=utf-8");

            // 把参数对象转成字符串
            String body = JSON.toJSONString(wxPayOrderVo);

            // 设置请求体
            post.setEntity(new StringEntity(body, "UTF-8"));
            // 获取返回对象
            CloseableHttpResponse response = client.execute(post);
            // 整理返回值
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);

            // 把返回的结果转成对象
//            JSONObject jsonObject = JSON.parseObject(result);
//            Boolean success = jsonObject.getBoolean("success");
//            if(success) {
//                JSONObject data = jsonObject.getJSONObject("data");
//                String codeUrl = data.getString("codeUrl");
//
//                return ResultResponse.SUCCESS(codeUrl);
//            }

            ResultResponse resultResponse = JSON.parseObject(result, ResultResponse.class);
            return resultResponse;

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

        return ResultResponse.FAILED(500, "支付发生未知错误");
    }

    @Override
    public ResultResponse getOderState(OrderNoInfoVo orderNoInfoVo) {
        String apiUrl = "https://www.shenmazong.com/weixin/getOrderInfo?orderNo="+orderNoInfoVo.getOrderNo();

        try {
            // 创建客户端连接对象
            CloseableHttpClient client = HttpClients.createDefault();
            // 构建Get请求对象
            HttpGet get = new HttpGet(apiUrl);

            CloseableHttpResponse response = client.execute(get);

            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity);

            log.info("getOderState" + body);
            ResultResponse resultResponse = JSON.parseObject(body, ResultResponse.class);
            return resultResponse;

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

        return ResultResponse.FAILED(500, "获取订单状态发生未知错误");
    }

    /**
     * 把订单设置为支付状态
     * @param orderNoInfoVo
     * @return
     */
    @Override
    public ResultResponse changeOrderState(OrderNoInfoVo orderNoInfoVo) {

        QueryWrapper<TbOrder> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(TbOrder::getOrderNo, orderNoInfoVo.getOrderNo()).last("limit 1");
        TbOrder one = getOne(wrapper);
        if(one == null) {
            return ResultResponse.FAILED(404, "订单不存在");
        }

        //
        one.setOrderState(OrderStateEnum.ORDER_PAYED.getCode());
        one.setUpdateTime(null);
        updateById(one);

        return ResultResponse.SUCCESS();
    }

    /**
     * 获取支付宝二维码
     * @param wxPayOrderVo
     * @return
     */

    @Override
    public ResultResponse getAlipayCode(WxPayOrderVo wxPayOrderVo) {
        String apiUrl = "https://www.shenmazong.com/alipay/postOrderObj";

        try {
            // 创建客户端连接对象
            CloseableHttpClient client = HttpClients.createDefault();

            // 构建Post请求对象
            HttpPost post = new HttpPost(apiUrl);
            // 设置传送的内容类型是json格式
            post.setHeader("Content-Type", "application/json;charset=utf-8");
            // 接收的内容类型也是json格式
            post.setHeader("Accept", "application/json;charset=utf-8");

            // 把参数对象转成字符串
            String body = JSON.toJSONString(wxPayOrderVo);

            // 设置请求体
            post.setEntity(new StringEntity(body, "UTF-8"));
            // 获取返回对象
            CloseableHttpResponse response = client.execute(post);
            // 整理返回值
            HttpEntity entity = response.getEntity();
            String result = EntityUtils.toString(entity);

            // 把返回的结果转成对象
            ResultResponse resultResponse = JSON.parseObject(result, ResultResponse.class);
            return resultResponse;

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
        }

        return ResultResponse.FAILED(500, "支付发生未知错误");
    }
}




